﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Management;
using System.Globalization;

/// <bugs>
/// if you right click the computer in the treeview, and error is cast becasue it is the root element
/// </bugs>

/// <notes>
/// nodes are displayed twice at startup if folders are displayed. PopulateDirectory2 fires AfterSelect upon finish
/// when starting up a saved node, the main node isn't displayed. How can one save a node from session to session?
/// </notes>


namespace MetaBabel2
{
    public partial class Form1 : Form
    {
        private string strCurrentNodeFullPretty = "";
        private string strCurrentNodeFull = "";
        private TreeNode currentTreeNode = null;
        private string strZoomNodePath = "";
        private bool boolTreeZoomed = false;

        public Form1()
        {
            this.Closing += new CancelEventHandler(Form1_Closing);
            InitializeComponent();
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.strLastOpenNode != "" && Properties.Settings.Default.strLastOpenNode != null)
            {
                PopulateDirectory2(Properties.Settings.Default.strLastOpenNode);
                //treeView1.Nodes.Clear();
                //treeView1.Nodes.Add(Properties.Settings.Default.nodeCurrentNode);
                //PopulateDirectory(Properties.Settings.Default.nodeCurrentNode);
            }
            else
            {
                PopulateDriveList();
            }
        }

        public void Form1_Closing(object sender, CancelEventArgs cArgs)
        {
            if (sender == this)
            {
                //MessageBox.Show("Form Closing Event....");

                //if (strCurrentNodeFull != "" && strCurrentNodeFull != null)
                //{
                    //Properties.Settings.Default.strLastOpenNode = strCurrentNodeFull;

                    Properties.Settings.Default.Save();
                //}

                if (sender != this)
                {
                    cArgs.Cancel = true;
                }
            }
        }
       
        ///

        //This procedure populate the TreeView with the Drive list
        private void PopulateDriveList()
        {
            TreeNode nodeTreeNode;
            int imageIndex = 0;
            int selectIndex = 0;

            const int Removable = 2;
            const int LocalDisk = 3;
            const int Network = 4;
            const int CD = 5;
            //const int RAMDrive = 6;

            boolTreeZoomed = false;
            Properties.Settings.Default.strLastOpenNode = "";

            this.Cursor = Cursors.WaitCursor;
            //clear TreeView
            treeView1.Nodes.Clear();
            nodeTreeNode = new TreeNode("Computer", 0, 0);
            nodeTreeNode.Tag = "Computer";
            treeView1.Nodes.Add(nodeTreeNode);

            //set node collection
            TreeNodeCollection nodeCollection = nodeTreeNode.Nodes;

            //Get Drive list
            ManagementObjectCollection queryCollection = getDrives();
            foreach (ManagementObject mo in queryCollection)
            {

                switch (int.Parse(mo["DriveType"].ToString()))
                {
                    case Removable:			//removable drives
                        imageIndex = 5;
                        selectIndex = 5;
                        break;
                    case LocalDisk:			//Local drives
                        imageIndex = 6;
                        selectIndex = 6;
                        break;
                    case CD:				//CD rom drives
                        imageIndex = 7;
                        selectIndex = 7;
                        break;
                    case Network:			//Network drives
                        imageIndex = 8;
                        selectIndex = 8;
                        break;
                    default:				//defalut to folder
                        imageIndex = 2;
                        selectIndex = 3;
                        break;
                }
                //create new drive node
                nodeTreeNode = new TreeNode(mo["Name"].ToString() + "\\", imageIndex, selectIndex);
                nodeTreeNode.Tag = mo["Name"].ToString() + "\\";

                //add new node
                nodeCollection.Add(nodeTreeNode);

            }


            //Init files ListView
            InitListView();

            this.Cursor = Cursors.Default;

        }

        private void tvFolders_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
            ////Populate folders and files when a folder is selected
            //this.Cursor = Cursors.WaitCursor;

            ////get current selected drive or folder
            //TreeNode nodeCurrent = e.Node;

            ////clear all sub-folders
            //nodeCurrent.Nodes.Clear();

            //if (nodeCurrent.SelectedImageIndex == 0)
            //{
            //    //Selected My Computer - repopulate drive list
            //    PopulateDriveList();
            //}
            //else
            //{
            //    //populate sub-folders and folder files
            //    PopulateDirectory(nodeCurrent, nodeCurrent.Nodes);
            //}
            //this.Cursor = Cursors.Default;
        }

        protected void InitListView()
        {
            ////init ListView control
            //lvFiles.Clear();		//clear control
            ////create column header for ListView
            //lvFiles.Columns.Add("Name", 150, System.Windows.Forms.HorizontalAlignment.Left);
            //lvFiles.Columns.Add("Size", 75, System.Windows.Forms.HorizontalAlignment.Right);
            //lvFiles.Columns.Add("Created", 140, System.Windows.Forms.HorizontalAlignment.Left);
            //lvFiles.Columns.Add("Modified", 140, System.Windows.Forms.HorizontalAlignment.Left);

        }

        protected void PopulateDirectory(TreeNode nodeCurrent)
        {
            TreeNode nodeDir;
            int imageIndex = 2;		//unselected image index
            int selectIndex = 3;	//selected image index

            if (nodeCurrent.SelectedImageIndex != 0)
            {
                //populate treeview with folders
                try
                {
                    //check path
                    if (Directory.Exists(getFullPath(nodeCurrent.Tag.ToString())) == false)
                    {
                        MessageBox.Show("Directory or path " + nodeCurrent.ToString() + " does not exist.");
                    }
                    else
                    {
                        //populate files
                        PopulateFiles(nodeCurrent);

                        string[] stringDirectories = Directory.GetDirectories(getFullPath(nodeCurrent.Tag.ToString()));
                        string stringFullPath = "";
                        string stringPathName = "";
                        TreeNodeCollection nodeCurrentCollection = nodeCurrent.Nodes;
                        //loop throught all directories
                        foreach (string stringDir in stringDirectories)
                        {
                            stringFullPath = stringDir;
                            stringPathName = GetPathName(stringFullPath);

                            //create node for directories
                            nodeDir = new TreeNode(stringPathName.ToString(), imageIndex, selectIndex);
                            nodeDir.Tag = stringFullPath;
                            nodeCurrentCollection.Add(nodeDir);
                        }
                    }
                }
                catch (IOException e)
                {
                    MessageBox.Show("Error: Drive not ready or directory does not exist.");
                }
                catch (UnauthorizedAccessException e)
                {
                    MessageBox.Show("Error: Drive or directory access denided.");
                }
                catch (Exception e)
                {
                    MessageBox.Show("Error: " + e);
                }
            }
        }

        protected string GetPathName(string stringPath)
        {
            //Get Name of folder
            string[] stringSplit = stringPath.Split('\\');
            int _maxIndex = stringSplit.Length;
            return stringSplit[_maxIndex - 1];
        }

        protected void PopulateFiles(TreeNode nodeCurrent)
        {
            return;
            //Populate listview with files
            string[] lvData = new string[4];

            //clear list
            InitListView();

            if (nodeCurrent.SelectedImageIndex != 0)
            {
                //check path
                if (Directory.Exists((string)getFullPath(nodeCurrent.FullPath)) == false)
                {
                    MessageBox.Show("Directory or path " + nodeCurrent.ToString() + " does not exist.");
                }
                else
                {
                    try
                    {
                        string[] stringFiles = Directory.GetFiles(getFullPath(nodeCurrent.FullPath));
                        string stringFileName = "";
                        DateTime dtCreateDate, dtModifyDate;
                        Int64 lFileSize = 0;

                        //loop throught all files
                        foreach (string stringFile in stringFiles)
                        {
                            stringFileName = stringFile;
                            FileInfo objFileSize = new FileInfo(stringFileName);
                            lFileSize = objFileSize.Length;
                            dtCreateDate = objFileSize.CreationTime; //GetCreationTime(stringFileName);
                            dtModifyDate = objFileSize.LastWriteTime; //GetLastWriteTime(stringFileName);

                            //create listview data
                            lvData[0] = GetPathName(stringFileName);
                            lvData[1] = formatSize(lFileSize);

                            //check if file is in local current day light saving time
                            if (TimeZone.CurrentTimeZone.IsDaylightSavingTime(dtCreateDate) == false)
                            {
                                //not in day light saving time adjust time
                                lvData[2] = formatDate(dtCreateDate.AddHours(1));
                            }
                            else
                            {
                                //is in day light saving time adjust time
                                lvData[2] = formatDate(dtCreateDate);
                            }

                            //check if file is in local current day light saving time
                            if (TimeZone.CurrentTimeZone.IsDaylightSavingTime(dtModifyDate) == false)
                            {
                                //not in day light saving time adjust time
                                lvData[3] = formatDate(dtModifyDate.AddHours(1));
                            }
                            else
                            {
                                //not in day light saving time adjust time
                                lvData[3] = formatDate(dtModifyDate);
                            }


                            //Create actual list item
                            ListViewItem lvItem = new ListViewItem(lvData, 0);
                            //lvFiles.Items.Add(lvItem);


                        }
                    }
                    catch (IOException e)
                    {
                        MessageBox.Show("Error: Drive not ready or directory does not exist.");
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        MessageBox.Show("Error: Drive or directory access denided.");
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show("Error: " + e);
                    }
                }
            }
        }

        protected string getFullPath(string stringPath)
        {
            //Get Full path
            string stringParse = "";
            //remove My Computer from path.
            stringParse = stringPath.Replace("Computer\\", "");

            return stringParse;
        }

        protected ManagementObjectCollection getDrives()
        {
            //get drive collection
            ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * From Win32_LogicalDisk ");
            ManagementObjectCollection queryCollection = query.Get();

            return queryCollection;
        }

        protected string formatDate(DateTime dtDate)
        {
            //Get date and time in short format
            string stringDate = "";

            stringDate = dtDate.ToShortDateString().ToString() + " " + dtDate.ToShortTimeString().ToString();

            return stringDate;
        }

        protected string formatSize(Int64 lSize)
        {
            //Format number to KB
            string stringSize = "";
            NumberFormatInfo myNfi = new NumberFormatInfo();

            Int64 lKBSize = 0;

            if (lSize < 1024)
            {
                if (lSize == 0)
                {
                    //zero byte
                    stringSize = "0";
                }
                else
                {
                    //less than 1K but not zero byte
                    stringSize = "1";
                }
            }
            else
            {
                //convert to KB
                lKBSize = lSize / 1024;
                //format number with default format
                stringSize = lKBSize.ToString("n", myNfi);
                //remove decimal
                stringSize = stringSize.Replace(".00", "");
            }

            return stringSize + " KB";

        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //Populate folders and files when a folder is selected
            this.Cursor = Cursors.WaitCursor;

            //get current selected drive or folder
            TreeNode nodeCurrent = e.Node;

            //clear all sub-folders
            nodeCurrent.Nodes.Clear();

            if (nodeCurrent.SelectedImageIndex == 0)
            {
                //Selected My Computer - repopulate drive list
                PopulateDriveList();
            }
            else
            {
                //populate sub-folders and folder files
                if (boolTreeZoomed)
                {
                    PopulateDirectory2(strCurrentNodeFull);
                }
                else
                    PopulateDirectory(nodeCurrent);
            }
            this.Cursor = Cursors.Default;

        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            strCurrentNodeFull = e.Node.FullPath;
            currentTreeNode = e.Node;
            strCurrentNodeFullPretty = cleanNodeString(e.Node.FullPath); //set the current pretty node globally for later use
            if (e.Button == MouseButtons.Right) //if the right mouse button is clicked
            {
                treeView1.SelectedNode = treeView1.GetNodeAt(e.X, e.Y); //make sure the node you right clicked at is selected    
                //strCurrentNodeFull = e.Node.FullPath; //set the current node globally for later use
                contextMenuStrip1.Show(); //show the contextmenu
            }
            //strCurrentNodeFullPretty = cleanNodeString(e.Node.FullPath); //set the current pretty node globally for later use
            //strCurrentNodeFull = e.Node.FullPath; //set the current node globally for later use
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            //MessageBox.Show(strCurrentNodeFullPretty);

            //PopulateDirectory2(strCurrentNodeFull);
            if (currentTreeNode != null) {
                Properties.Settings.Default.strLastOpenNode = strCurrentNodeFull;
                treeView1.Nodes.Clear();                
                treeView1.Nodes.Add(currentTreeNode);
                PopulateDirectory(currentTreeNode);
            }
        }

        private string cleanNodeString(string nodeString)
        {
            if (nodeString.Length >= 12) //the string looks like "Computer\C:\\OML\XML export\Movie Collectorz" so the string must be at least 12 chars
            {
                nodeString = nodeString.Substring(9, nodeString.Length - 9); //remove the "Computer\" stuff
                if (nodeString.IndexOf("\\\\") > 0) //if the "\\\\" is in the string
                    nodeString.Replace("\\\\", "\\"); //replace it with just "\\"
            }
            return nodeString;
        }

        protected void PopulateDirectory2(string strFullPath)
        {
            TreeNode nodeDir;
            int imageIndex = 2;		//unselected image index
            int selectIndex = 3;	//selected image index

            //if (nodeCurrent.SelectedImageIndex != 0)
            //{

            if (strFullPath.Length < 8 && strZoomNodePath != "")
            {
                strFullPath = strZoomNodePath + "\\" + strFullPath;
            }


                //populate treeview with folders
                try
                {
                    //check path
                    if (Directory.Exists(getFullPath(strFullPath)) == false)
                    {
                        MessageBox.Show("Directory or path " + strFullPath + " does not exist.");
                    }
                    else
                    {
                        //populate files
                        //PopulateFiles(nodeCurrent);

                        string[] stringDirectories = Directory.GetDirectories(getFullPath(strFullPath));
                        string stringFullPath = "";
                        string stringPathName = "";

                        //loop throught all directories
                        foreach (string stringDir in stringDirectories)
                        {
                            stringFullPath = stringDir;
                            stringPathName = GetPathName(stringFullPath);

                            //create node for directories
                            nodeDir = new TreeNode(stringPathName.ToString(), imageIndex, selectIndex);
                            //nodeCurrentCollection.Add(nodeDir);
                            treeView1.Nodes.Add(nodeDir);  // adding to the tree instead of adding to the current nodes, this is where the error is!!

                        }
                        boolTreeZoomed = true;
                        strZoomNodePath = strFullPath;
                    }
                }
                catch (IOException e)
                {
                    MessageBox.Show("Error: Drive not ready or directory does not exist.");
                }
                catch (UnauthorizedAccessException e)
                {
                    MessageBox.Show("Error: Drive or directory access denided.");
                }
                catch (Exception e)
                {
                    MessageBox.Show("Error: " + e);
                }
            //}
        }

        private void newToolStripButton_Click(object sender, EventArgs e)
        {
            PopulateDriveList();
        }

        void HandleDynamicMenuClick(object sender, EventArgs e)
        {
            ToolStripItem item = (ToolStripItem)sender;
            MessageBox.Show("Selected menu " + item.Text);
        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            AddBookmark();
        }

        private void addBookmarkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddBookmark();
        }

        private void AddBookmark()
        {
            //MenuStrip MyMenu = menuStrip1;
            //ToolStripMenuItem m1 = helpToolStripMenuItem;
            //ToolStripMenuItem subm1 = new ToolStripMenuItem("Juhu");

            //helpToolStripMenuItem.DropDownItems.Add("Juhu");

            ToolStripMenuItem item = (ToolStripMenuItem)bookmarksToolStripMenuItem.DropDownItems.Add(DateTime.Now.ToString());
            item.Click += new EventHandler(HandleDynamicMenuClick);
        }
        
    }
}
